package m.store.service;

import com.sun.org.apache.xpath.internal.operations.Or;
import m.base.model.StoreInfo;
import m.base.model.UserInfo;
import m.base.util.PowerUtil;
import m.common.model.util.ModelQueryList;
import m.common.model.util.ModelUpdate;
import m.common.model.util.ModelUpdateUtil;
import m.common.model.util.QueryCondition;
import m.common.service.Service;
import m.fun.model.*;
import m.fun.service.CountInfoService;
import m.fun.service.ProduceInfoService;
import m.store.model.*;
import m.system.exception.MException;
import m.system.util.ArrayUtil;
import m.system.util.GenerateID;
import m.system.util.StringUtil;

import java.sql.SQLException;
import java.util.*;

public class OrderRepositoryCheckService extends Service {
    public void check(List<OrderRepositoryCheck> modelList,String status,String checkRemark) throws Exception {
        if(StringUtil.isSpace(status)) throw new MException(this.getClass(),"请选择审核结果");
        if(OrderRepositoryCheck.Status_No.equals(status)&&StringUtil.isSpace(checkRemark)){
            throw new MException(this.getClass(),"审核不通过需要填写审核备注");
        }
        Date date=new Date();
        Map<String,String> orderMap=new HashMap<>();
        modelList.forEach(item->{
            item.setStatus(status);
            item.setCheckRemark(checkRemark);
            item.setCheckDate(date);
            orderMap.put(item.getOrderOid(),item.getOrderNo());
        });
        ModelUpdateUtil.updateModels(modelList.toArray(new OrderRepositoryCheck[0]),"status","checkRemark","checkDate");
        if(OrderRepositoryCheck.Status_No.equals(status)){
            StoreInfo store=PowerUtil.getSessionStore(true);
            UserInfo user=PowerUtil.getSessionUser(true);
            for(String orderOid : orderMap.keySet()) {
                if (orderMap.get(orderOid).startsWith(StoreNumber.Type_Sale)) getService(SaleInfoService.class).refund(orderOid,store,user);
                else if (orderMap.get(orderOid).startsWith(StoreNumber.Type_Stock)) getService(StockInfoService.class).refund(orderOid,store,user);
                else if (orderMap.get(orderOid).startsWith(StoreNumber.Type_Count)) getService(CountInfoService.class).refund(orderOid,store,user);
                else if (orderMap.get(orderOid).startsWith(StoreNumber.Type_Produce)) getService(ProduceInfoService.class).refund(orderOid,store,user);
                ModelUpdate.init(OrderRepositoryCheck.class)
                    .set("status",OrderRepositoryCheck.Status_View)
                    .execute(QueryCondition.and(
                        QueryCondition.eq("orderOid",orderOid),
                        QueryCondition.eq("status",OrderRepositoryCheck.Status_Check)
                    ));
            }
        }else if(OrderRepositoryCheck.Status_Yes.equals(status)){
            for(String orderOid : orderMap.keySet()){
                if(isCheckOver(orderOid)){
                    OrderModel order=null;
                    if(orderMap.get(orderOid).startsWith(StoreNumber.Type_Sale)) order=new SaleInfo();
                    else if(orderMap.get(orderOid).startsWith(StoreNumber.Type_Stock)) order=new StockInfo();
                    else if(orderMap.get(orderOid).startsWith(StoreNumber.Type_Count)) order=new CountInfo();
                    else if(orderMap.get(orderOid).startsWith(StoreNumber.Type_Produce)) order=new ProduceInfo();
                    if(null!=order){
                        order.setOid(orderOid);
                        order.setRepositoryStatus(OrderRepositoryCheck.Status_Yes);
                        ModelUpdateUtil.updateModel(order,"repositoryStatus");
                    }
                }
            }
        }
    }


    /**
     * 是否全部审核完成，判断是否存在未审核通过的，没有则代表全部完成
     */
    public boolean isCheckOver(String orderOid) throws SQLException, MException {
        return ModelQueryList.getModelList(OrderRepositoryCheck.class,new String[]{"oid"},null,
            QueryCondition.and(
                QueryCondition.eq("orderOid",orderOid),
                QueryCondition.not(QueryCondition.eq("status",OrderRepositoryCheck.Status_Yes))
            )
        ).isEmpty();
    }
    /**
     * 验证是否全部审核通过，订单审核时调用
     */
    public void verifyCheckOver(String orderOid) throws SQLException, MException {
        verifyCheckOver(orderOid,true);
    }
    public String verifyCheckOver(String orderOid,boolean isThrow) throws SQLException, MException {
        List<OrderRepositoryCheck> ls=ModelQueryList.getModelList(OrderRepositoryCheck.class,new String[]{"checkUser.realname"},null,
            QueryCondition.and(
                QueryCondition.eq("orderOid",orderOid),
                QueryCondition.not(QueryCondition.eq("status",OrderRepositoryCheck.Status_Yes))
            )
        );
        if(!ls.isEmpty()) {
            String users=ArrayUtil.connection(ls.stream().map(item->item.getCheckUser().getRealname()).distinct().toArray(),"，");
            String msg="请等待仓库管理员审核，审核人："+users;
            if(isThrow)
                throw new MException(this.getClass(),msg);
            else
                return msg;
        }
        return null;
    }
    public <T extends OrderModel> void insertCheck(T order) throws Exception {
        ModelUpdateUtil.delete(OrderRepositoryCheck.class,QueryCondition.eq("orderOid",order.getOid()));
        if(PowerUtil.isRepositoryCheck()){
            int num=0;
            if(order instanceof SaleInfo) num=insert((SaleInfo) order);
            else if(order instanceof StockInfo) num=insert((StockInfo) order);
            else if(order instanceof CountInfo) num=insert((CountInfo) order);
            else if(order instanceof ProduceInfo) num=insert((ProduceInfo) order);
            order.setRepositoryStatus(num>0?OrderRepositoryCheck.Status_Check:null);
        }else{
            order.setRepositoryStatus(null);
        }
        ModelUpdateUtil.updateModel(order,"repositoryStatus");
    }
    private <T extends OrderModel> OrderRepositoryCheck toModel(T order,String orderType){
        OrderRepositoryCheck model=new OrderRepositoryCheck();
        model.setOid(GenerateID.generatePrimaryKey());
        model.setOrderType(orderType);
        model.setOrderOid(order.getOid());
        model.setOrderNo(order.getOrderNo());
        model.setStatus(OrderRepositoryCheck.Status_Check);
        if(order instanceof SaleInfo) {
            model.setOrderDate(((SaleInfo)order).getSaleDate());
        }else if(order instanceof StockInfo) {
            model.setOrderDate(((StockInfo)order).getStockDate());
        }else if(order instanceof CountInfo) {
            model.setOrderDate(((CountInfo)order).getCountDate());
        }else if(order instanceof ProduceInfo) {
            model.setOrderDate(((ProduceInfo)order).getProduceDate());
        }
        return model;
    }
    /**
     * 根据出库生成审核记录
     */
    private int insert(SaleInfo sale) throws MException, SQLException {
        List<GoodsOutRecord> ls=ModelQueryList.getModelList(GoodsOutRecord.class,new String[]{"*","record.repository.*"},null,
            QueryCondition.and(
                QueryCondition.eq("sale.oid",sale.getOid()),
                QueryCondition.notEmpty("record.repository.oid")
            )
        );
        List<OrderRepositoryCheck> inserts=new ArrayList<>();
        for(GoodsOutRecord r : ls){
            OrderRepositoryCheck model=toModel(sale,
                sale.getType().equals(SaleInfo.Type_Refund)?OrderRepositoryCheck.OrderType_StockRefund:OrderRepositoryCheck.OrderType_Sale
            );
            model.setRepository(r.getRecord().getRepository());
            model.setCheckUser(r.getRecord().getRepository().getManageUser());
            model.setStockRecord(r.getRecord());
            model.setGoods(r.getGoods());
            model.setPrice(r.getPrice());
            model.setNum(r.getNum());
            model.setPreferential(r.getPreferential());
            model.setAmount(r.getSaleAmount());
            model.setPreferentialPrice(r.getPreferentialPrice());
            model.setRemark(r.getRemark());
            inserts.add(model);
        }
        if(!inserts.isEmpty()) ModelUpdateUtil.insertModels(inserts.toArray(new OrderRepositoryCheck[0]));
        return inserts.size();
    }

    /**
     * 根据入库生成审核记录
     */
    private int insert(StockInfo stock) throws MException, SQLException {
        List<GoodsStockRecord> ls=ModelQueryList.getModelList(GoodsStockRecord.class,new String[]{"*","repository.*"},null,
            QueryCondition.and(
                QueryCondition.eq("stock.oid",stock.getOid()),
                QueryCondition.notEmpty("repository.oid")
            )
        );
        List<OrderRepositoryCheck> inserts=new ArrayList<>();
        for(GoodsStockRecord r : ls){
            OrderRepositoryCheck model=toModel(stock,
                    stock.getType().equals(StockInfo.Type_Refund)?OrderRepositoryCheck.OrderType_SaleRefund:OrderRepositoryCheck.OrderType_Stock
            );
            model.setRepository(r.getRepository());
            model.setCheckUser(r.getRepository().getManageUser());
//            model.setStockRecord(r);
            model.setGoods(r.getGoods());
            model.setPrice(r.getPrice());
            model.setNum(r.getStockNum());
            model.setPreferential(r.getPreferential());
            model.setAmount(r.getStockAmount());
            model.setPreferentialPrice(r.getPreferentialPrice());
            model.setRemark(r.getRemark());
            inserts.add(model);
        }
        if(!inserts.isEmpty()) ModelUpdateUtil.insertModels(inserts.toArray(new OrderRepositoryCheck[0]));
        return inserts.size();
    }

    /**
     * 根据盘点生成审核记录
     */
    private int insert(CountInfo count) throws MException, SQLException {
        List<CountDetail> ls=ModelQueryList.getModelList(CountDetail.class,new String[]{"*","record.repository.*"},null,
            QueryCondition.and(
                QueryCondition.eq("count.oid",count.getOid()),
                QueryCondition.notEmpty("record.repository.oid")
            )
        );
        List<OrderRepositoryCheck> inserts=new ArrayList<>();
        for(CountDetail r : ls){
            OrderRepositoryCheck model=toModel(count,
                r.getNum()>0?OrderRepositoryCheck.OrderType_CountStock:OrderRepositoryCheck.OrderType_CountSale
            );
            model.setRepository(r.getRecord().getRepository());
            model.setCheckUser(r.getRecord().getRepository().getManageUser());
            model.setStockRecord(r.getNum()>0?null:r.getRecord());
            model.setGoods(r.getGoods());
            model.setPrice(r.getPrice());
            model.setNum(r.getNum()>0?r.getNum():-r.getNum());
            model.setPreferential(r.getNum()>0?r.getPreferential():-r.getPreferential());
            model.setAmount(r.getNum()>0?r.getAmount():-r.getAmount());
            model.setPreferentialPrice(r.getPreferentialPrice());
            model.setRemark(r.getRemark());
            inserts.add(model);
        }
        if(!inserts.isEmpty()) ModelUpdateUtil.insertModels(inserts.toArray(new OrderRepositoryCheck[0]));
        return inserts.size();
    }

    /**
     * 根据生产生成审核记录
     */
    private int insert(ProduceInfo produce) throws MException, SQLException {
        List<ProduceInGoods> ls1=ModelQueryList.getModelList(ProduceInGoods.class,new String[]{"*","repository.*"},null,
            QueryCondition.and(
                QueryCondition.eq("produce.oid",produce.getOid()),
                QueryCondition.notEmpty("repository.oid")
            )
        );
        List<OrderRepositoryCheck> inserts=new ArrayList<>();
        for(ProduceInGoods r : ls1){
            OrderRepositoryCheck model=toModel(produce,OrderRepositoryCheck.OrderType_ProduceStock);
            model.setRepository(r.getRepository());
            model.setCheckUser(r.getRepository().getManageUser());
//            model.setStockRecord(r);
            model.setGoods(r.getGoods());
            model.setPrice(r.getPrice());
            model.setNum(r.getNum());
            model.setPreferential(r.getPreferential());
            model.setAmount(r.getAmount());
            model.setPreferentialPrice(r.getPreferentialPrice());
            model.setRemark(r.getRemark());
            inserts.add(model);
        }
        List<ProduceOutGoods> ls2=ModelQueryList.getModelList(ProduceOutGoods.class,new String[]{"*","record.repository.*"},null,
            QueryCondition.and(
                QueryCondition.eq("produce.oid",produce.getOid()),
                QueryCondition.notEmpty("record.repository.oid")
            )
        );
        for(ProduceOutGoods r : ls2){
            OrderRepositoryCheck model=toModel(produce,OrderRepositoryCheck.OrderType_ProduceSale);
            model.setRepository(r.getRecord().getRepository());
            model.setCheckUser(r.getRecord().getRepository().getManageUser());
            model.setStockRecord(r.getRecord());
            model.setGoods(r.getGoods());
            model.setPrice(r.getPrice());
            model.setNum(r.getNum());
            model.setPreferential(r.getPreferential());
            model.setAmount(r.getAmount());
            model.setPreferentialPrice(r.getPreferentialPrice());
            model.setRemark(r.getRemark());
            inserts.add(model);
        }
        if(!inserts.isEmpty()) ModelUpdateUtil.insertModels(inserts.toArray(new OrderRepositoryCheck[0]));
        return inserts.size();
    }
}
